﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Diagnostics;
using LogLib;

namespace IPCPages
{
    public delegate void ReciveProgramMessage(string program, int code, string msg);

    public class PipelinePool
    {
        private static bool _running = false;

        public static event ReciveProgramMessage MsgRecived;
        public static void OnMsgReceived(string text, int code, string msg)
        {
            if (MsgRecived != null)
            {
                MsgRecived(text, code, msg);
            }
        }

        /// <summary>
        /// 用于存储和管理管道的进程池
        /// </summary>
        private static ConcurrentDictionary<Guid, Pipeline> ServerPool = new ConcurrentDictionary<Guid, Pipeline>();

        /// <summary>
        /// 创建一个新的管道
        /// </summary>
        private static void CreatePipeLine()
        {
            if(!_running)
            {
                _running = true;
            }
            lock (ServerPool)
            {
                if (ServerPool.Count < Pipeline.MaxServer)
                {
                    var pipe = new Pipeline();
                    pipe.Start();
                    ServerPool.TryAdd(pipe.ID, pipe);
                }
            }
            Log.WriteAsync(string.Format("管道池添加新管道, 当前管道总数{0}", ServerPool.Count));
        }

        /// <summary>
        /// 根据ID从管道池中释放一个管道
        /// </summary>
        private static void DisposablePipeLine(Guid Id)
        {
            lock (ServerPool)
            {
                Log.WriteAsync(string.Format("开始尝试释放,管道{0}", Id));
                Pipeline pipe = null;
                if (ServerPool.TryRemove(Id, out pipe))
                {
                    Log.WriteAsync(string.Format("管道{0},已经关闭,并完成资源释放", Id));
                }
                else
                {
                    Log.WriteAsync(string.Format("未找到ID为{0}的管道", Id));
                }
                if (ServerPool.Count == 0 && _running)
                {
                    CreatePipeLine();
                }
            }
        }

        /// <summary>
        /// (异步)创建一个新的管道进程
        /// </summary>
        public static void CreatePipeLineAsync()
        {
            Task.Factory.StartNew(new Action(CreatePipeLine));
        }

        /// <summary>
        /// (异步)根据ID从管道池中释放一个管道
        /// </summary>
        /// <param name="id"></param>
        public static void DisposablePipeLineAsync(Guid id)
        {
            Task.Factory.StartNew(() => { DisposablePipeLine(id); });
        }

        public static void Exit()
        {
            _running = false;
            var pipes = ServerPool.Values.ToList();
            for (int i = 0; i < pipes.Count; i++)
            {
                pipes[i].Stop();
            }
        }
    }
}
